#include "messagetextedit.h"
#include <QFileIconProvider>
#include <QFileInfo>
#include <QFontMetrics>
#include <QImage>
#include <QPainter>
MessageTextEdit::MessageTextEdit(QWidget *parent)
    : QTextEdit(parent)
{
    this->setMaximumHeight(60);
}

MessageTextEdit::~MessageTextEdit() {}

QVector<MsgInfo> MessageTextEdit::getMsgList()
{
    _getMsgList.clear();
    // 获取输入内容
    QString doc = this->document()->toPlainText();
    QString text = "";
    int indexUrl = 0;
    // 消息列表长度
    int count = _msgList.size();
    // 遍历消息文本
    for (int i = 0; i < doc.size(); i++) {
        // 非文本内容占位符
        if (doc[i] == QChar::ObjectReplacementCharacter) {
            // 文本编辑框中同时存在文字和非文字内容
            if (!text.isEmpty()) {
                // 将消息加入消息列表
                QPixmap pix;
                insertMsgList(_getMsgList, "text", text, pix);
                text.clear();
            }
            while (indexUrl < count) {
                // 从消息列表中拿出一个消息
                MsgInfo msg = _msgList[indexUrl];
                if (document()->toHtml().contains(msg.content, Qt::CaseSensitive)) {
                    indexUrl++;
                    _getMsgList.append(msg);
                    break;
                }
                indexUrl++;
            }
        } else {
            // 纯文本内容
            text.append(doc[i]);
        }
    }
    if (!text.isEmpty()) {
        QPixmap pix;
        insertMsgList(_getMsgList, "text", text, pix);
        text.clear();
    }
    _msgList.clear();
    this->clear();
    return _getMsgList;
}

void MessageTextEdit::insertFileFromUrl(const QStringList &urls)
{
    if (urls.isEmpty()) {
        return;
    }
    foreach (QString url, urls) {
        if (isImage(url)) {
            insertImage(url);
        } else {
            insertTextFile(url);
        }
    }
}

void MessageTextEdit::keyPressEvent(QKeyEvent *event)
{
    // Enter
    // Qt::Key_Return 主键盘回车键
    // Qt::Key_Return 小键盘回车键
    if ((event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return)
        && !(event->modifiers() & Qt::ShiftModifier)) {
        emit send();
        return;
    }
    QTextEdit::keyPressEvent(event);
}

void MessageTextEdit::dragEnterEvent(QDragEnterEvent *event)
{
    if (event->source() == this) {
        event->ignore();
    } else {
        event->accept();
    }
}

void MessageTextEdit::dropEvent(QDropEvent *event)
{
    insertFromMimeData(event->mimeData());
    event->accept();
}

void MessageTextEdit::insertImage(const QString &url)
{
    QImage image(url);
    if (image.width() > IMAGE_MAX_WIDTH || image.height() > IMAGE_MAX_HEIGHT) {
        if (image.width() > image.height()) {
            image = image.scaledToWidth(IMAGE_MAX_WIDTH, Qt::SmoothTransformation);
        } else {
            image = image.scaledToHeight(IMAGE_MAX_HEIGHT, Qt::SmoothTransformation);
        }
    }
    QTextCursor cursor = this->textCursor();
    cursor.insertImage(image, url);
    insertMsgList(_msgList, "image", url, QPixmap::fromImage(image));
}

void MessageTextEdit::insertTextFile(const QString &url) {}

bool MessageTextEdit::canInsertFromMimeData(const QMimeData *source) const
{
    return QTextEdit::canInsertFromMimeData(source);
}

void MessageTextEdit::insertFromMimeData(const QMimeData *source)
{
    QStringList urls = getUrl(source->text());
    if (urls.isEmpty())
        return;
    foreach (QString url, urls) {
        if (isImage((url))) {
            insertImage(url);
        } else {
            insertTextFile(url);
        }
    }
}

bool MessageTextEdit::isImage(QString url)
{
    QString imageFormat = "bmp,jpg,png,tif,gif,pcx,tga,exif,svg,raw,";
    QStringList imageFormatList = imageFormat.split(",");
    QFileInfo fileInfo(url);
    QString suffix = fileInfo.suffix().toLower();
    if (imageFormatList.contains(suffix)) {
        return true;
    } else {
        return false;
    }
}

void MessageTextEdit::insertMsgList(QVector<MsgInfo> &list, QString flag, QString text, QPixmap pix)
{
    MsgInfo msg;
    msg.msgFlag = flag;
    msg.content = text;
    msg.pixmap = pix;
    list.append(msg);
}

QStringList MessageTextEdit::getUrl(QString text)
{
    QStringList urls;
    if (text.isEmpty())
        return urls;
    QStringList list = text.split("\n");
    foreach (QString url, list) {
        if (!url.isEmpty()) {
            QStringList str = url.split("///");
            if (str.size() >= 2) {
                urls.append(str.at(1));
            }
        }
    }
    return urls;
}

QPixmap MessageTextEdit::getFileIconPixmap(const QString &url)
{
    QFileIconProvider provder;
    QFileInfo fileInfo(url);
    QIcon icon = provder.icon(fileInfo);
    QString strFileSize = getFileSize(fileInfo.size());

    QFont font(QString("宋体"), 10, QFont::Normal, false);
    QFontMetrics fontMetrics(font);
    QSize textSize = fontMetrics.size(Qt::TextSingleLine, fileInfo.fileName());

    QSize fileSize = fontMetrics.size(Qt::TextSingleLine, strFileSize);
    int maxWidth = textSize.width() > fileSize.width() ? textSize.width() : fileSize.width();
    QPixmap pix(50 + maxWidth + 10, 50);
    pix.fill();

    QPainter painter;
    painter.begin(&pix);
    // 文件图标
    QRect rect(0, 0, 50, 50);
    painter.drawPixmap(rect, icon.pixmap(40, 40));
    painter.setPen(Qt::black);
    // 文件名称
    QRect rectText(50 + 10, 3, textSize.width(), textSize.height());
    painter.drawText(rectText, fileInfo.fileName());
    // 文件大小
    QRect rectFile(50 + 10, textSize.height() + 5, fileSize.width(), fileSize.height());
    painter.drawText(rectFile, strFileSize);
    painter.end();
    return pix;
}

QString MessageTextEdit::getFileSize(qint64 size)
{
    QString Uint;
    double num;
    if (size < 1024) {
        num = size;
        Uint = "B";
    } else if (size < 1024 * 1024) {
        num = size / 1024.0;
        Uint = "KB";
    } else if (size < 1024 * 1024 * 1024) {
        num = size / 1024.0 / 1024.0 / 1024.0;
        Uint = "MB";
    } else {
        num = size / 1024.0 / 1024.0 / 1024.0 / 1024.0;
        Uint = "GB";
    }
    return QString::number(num, 'f', 2) + " " + Uint;
}

void MessageTextEdit::textEditChanged() {}
